package com.spsoft.dmzeinvoice.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.reflect.TypeToken;
import com.spsoft.core.constants.CommonConstants;
import com.spsoft.core.model.Result;
import com.spsoft.core.model.leqidmz.param.BaseUserInfoParam;
import com.spsoft.core.model.leqidmz.param.LeqiHeader;
import com.spsoft.core.model.leqidmz.param.collect.*;
import com.spsoft.core.model.leqidmz.response.QueryDifferentialTaxationVO;
import com.spsoft.core.model.leqidmz.response.QueryEnterpriseInfoVO;
import com.spsoft.core.model.leqidmz.response.collect.*;
import com.spsoft.dmzeinvoice.common.enums.LeqiAbilityEnum;
import com.spsoft.dmzeinvoice.common.enums.LeqiApiEnum;
import com.spsoft.dmzeinvoice.common.enums.TdysEnum;
import com.spsoft.dmzeinvoice.common.utils.LeqiMockUtil;
import com.spsoft.dmzeinvoice.common.utils.LeqiResultUtil;
import com.spsoft.dmzeinvoice.common.utils.RestTemplateUtil;
import com.spsoft.dmzeinvoice.model.vo.LeqiResult;
import com.spsoft.dmzeinvoice.service.VmsCollectInvoiceService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.lang.reflect.Type;

/**
 * 乐企接口-归集-发票相关实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
@SuppressWarnings({"unchecked"})
public class VmsCollectInvoiceServiceImpl implements VmsCollectInvoiceService {

    private final RestTemplateUtil restTemplateUtil;

    // 是否返回模拟数据
    @Value("${leqi.mockFlag}")
    private boolean mockFlag;

    // 调用乐企的请求地址
    @Value("${leqi.url}")
    private String url;

    // 乐企接入单位平台编号
    @Value("${leqi.jrdwptbh}")
    private String jrdwptbh;

    // 乐企沙箱测试标志
    @Value("${leqi.sxcsbz:}")
    private String sxcsbz;


    /**
     * 批量发票下载申请
     */
    @Override
    public Result<BatchLoadInvoiceVO> batchLoadInvoice(BatchLoadInvoiceParam params) {
        // 组装请求头
        LeqiHeader leqiHeader = buildHeader(params, LeqiApiEnum.PLFPXZSQ);

        String responseStr;
        String requestJson = JSONObject.toJSONString(params);

        if (mockFlag) {
            // Mock数据
            responseStr = LeqiMockUtil.getBatchLoadInvoiceStr();
        } else {
            // 调乐企接口
            responseStr = restTemplateUtil.postLeQi(leqiHeader, requestJson);
        }

        Type type = new TypeToken<LeqiResult<String>>(){}.getType();
        LeqiResult<String> leqiResult = LeqiResultUtil.jsonToLeqiResult(responseStr, type);
        LeqiResult.ErrorInfo errorInfo = leqiResult.getResponse().getError();
        // 有error节点，返回error
        if (errorInfo != null) {
            return Result.ERRORT(errorInfo.getCode(), errorInfo.getMessage());
        }
        BatchLoadInvoiceVO resultVo = JSONObject.parseObject(leqiResult.getResponse().getData(), BatchLoadInvoiceVO.class);
        // 业务层不为00，返回error
        if (!CommonConstants.LEQI_SUCCESS.equals(resultVo.getReturncode())) {
            return Result.ERRORT(resultVo.getReturncode(), resultVo.getReturnmsg());
        }

        return Result.OK(resultVo);
    }

    /**
     * 批量发票下载申请反馈
     */
    @Override
    public Result<BatchLoadInvoiceFeedbackVO> batchLoadInvoiceFeedback(BatchLoadInvoiceFeedbackParam params) {
        // 组装请求头
        LeqiHeader leqiHeader = buildHeader(params, LeqiApiEnum.PLFPXZSQFK);

        String responseStr;
        String requestJson = JSONObject.toJSONString(params);

        if (mockFlag) {
            // Mock数据
            responseStr = LeqiMockUtil.getBatchLoadInvoiceFeedbackStr();
        } else {
            // 调乐企接口
            responseStr = restTemplateUtil.postLeQi(leqiHeader, requestJson);
        }

        Type type = new TypeToken<LeqiResult<String>>(){}.getType();
        LeqiResult<String> leqiResult = LeqiResultUtil.jsonToLeqiResult(responseStr, type);
        LeqiResult.ErrorInfo errorInfo = leqiResult.getResponse().getError();
        // 有error节点，返回error
        if (errorInfo != null) {
            return Result.ERRORT(errorInfo.getCode(), errorInfo.getMessage());
        }
        BatchLoadInvoiceFeedbackVO resultVo = JSONObject.parseObject(leqiResult.getResponse().getData(), BatchLoadInvoiceFeedbackVO.class);
        // 业务层不为00，返回error
        if (!CommonConstants.LEQI_SUCCESS.equals(resultVo.getReturncode())) {
            return Result.ERRORT(resultVo.getReturncode(), resultVo.getReturnmsg());
        }

        return Result.OK(resultVo);
    }

    /**
     * 查询增量下载发票信息
     */
    @Override
    public Result<IncLoadInvoiceQueryVO> incLoadInvoiceQuery(IncLoadInvoiceQueryParam params) {
        // 组装请求头
        LeqiHeader leqiHeader = buildHeader(params, LeqiApiEnum.CXZLXZFPXX);

        String responseStr;
        String requestJson = JSONObject.toJSONString(params);

        if (mockFlag) {
            // Mock数据
            responseStr = LeqiMockUtil.getIncLoadInvoiceQueryStr();
        } else {
            // 调乐企接口
            responseStr = restTemplateUtil.postLeQi(leqiHeader, requestJson);
        }

        Type type = new TypeToken<LeqiResult<String>>(){}.getType();
        LeqiResult<String> leqiResult = LeqiResultUtil.jsonToLeqiResult(responseStr, type);
        LeqiResult.ErrorInfo errorInfo = leqiResult.getResponse().getError();
        // 有error节点，返回error
        if (errorInfo != null) {
            return Result.ERRORT(errorInfo.getCode(), errorInfo.getMessage());
        }
        IncLoadInvoiceQueryVO resultVo = JSONObject.parseObject(leqiResult.getResponse().getData(), IncLoadInvoiceQueryVO.class);
        // 业务层不为00，返回error
        if (!CommonConstants.LEQI_SUCCESS.equals(resultVo.getReturncode())) {
            return Result.ERRORT(resultVo.getReturncode(), resultVo.getReturnmsg());
        }

        return Result.OK(resultVo);
    }

    /**
     * 发票风险信息查询
     */
    @Override
    public Result<InvoiceRiskQueryVO> invoiceRiskQuery(InvoiceRiskQueryParam params) {
        // 组装请求头
        LeqiHeader leqiHeader = buildHeader(params, LeqiApiEnum.FPTSTXXXCX);

        String responseStr;
        String requestJson = JSONObject.toJSONString(params);

        if (mockFlag) {
            // Mock数据
            responseStr = LeqiMockUtil.getInvoiceRiskQueryStr();
        } else {
            // 调乐企接口
            responseStr = restTemplateUtil.postLeQi(leqiHeader, requestJson);
        }

        Type type = new TypeToken<LeqiResult<String>>(){}.getType();
        LeqiResult<String> leqiResult = LeqiResultUtil.jsonToLeqiResult(responseStr, type);
        LeqiResult.ErrorInfo errorInfo = leqiResult.getResponse().getError();
        // 有error节点，返回error
        if (errorInfo != null) {
            return Result.ERRORT(errorInfo.getCode(), errorInfo.getMessage());
        }
        InvoiceRiskQueryVO resultVo = JSONObject.parseObject(leqiResult.getResponse().getData(), InvoiceRiskQueryVO.class);
        // 业务层不为00，返回error
        if (!CommonConstants.LEQI_SUCCESS.equals(resultVo.getReturncode())) {
            return Result.ERRORT(resultVo.getReturncode(), resultVo.getReturnmsg());
        }

        return Result.OK(resultVo);
    }

    /**
     * 发票用途状态信息查询
     */
    @Override
    public Result<InvoiceUsedStatusQueryVO> invoiceUsedStatusQuery(InvoiceUsedStatusQueryParam params) {
        // 组装请求头
        LeqiHeader leqiHeader = buildHeader(params, LeqiApiEnum.FPZTXXCX);

        String responseStr;
        String requestJson = JSONObject.toJSONString(params);

        if (mockFlag) {
            // Mock数据
            responseStr = LeqiMockUtil.getInvoiceUsedStatusQueryStr();
        } else {
            // 调乐企接口
            responseStr = restTemplateUtil.postLeQi(leqiHeader, requestJson);
        }

        Type type = new TypeToken<LeqiResult<String>>(){}.getType();
        LeqiResult<String> leqiResult = LeqiResultUtil.jsonToLeqiResult(responseStr, type);
        LeqiResult.ErrorInfo errorInfo = leqiResult.getResponse().getError();
        // 有error节点，返回error
        if (errorInfo != null) {
            return Result.ERRORT(errorInfo.getCode(), errorInfo.getMessage());
        }
        InvoiceUsedStatusQueryVO resultVo = JSONObject.parseObject(leqiResult.getResponse().getData(), InvoiceUsedStatusQueryVO.class);
        // 业务层不为00，返回error
        if (!CommonConstants.LEQI_SUCCESS.equals(resultVo.getReturncode())) {
            return Result.ERRORT(resultVo.getReturncode(), resultVo.getReturnmsg());
        }

        return Result.OK(resultVo);
    }

    /**
     * 构建乐企请求头信息
     * @param params 入参
     * @param leqiApiEnum 乐企服务编码枚举
     */
    private LeqiHeader buildHeader(BaseUserInfoParam params, LeqiApiEnum leqiApiEnum) {
        LeqiHeader leqiHeader = new LeqiHeader();
        LeqiAbilityEnum leqiAbility;
        if (TdysEnum.TDYS_05.getCode().equals(params.getTdys())) {
            leqiAbility = LeqiAbilityEnum.BDCXS;
        } else if (TdysEnum.TDYS_06.getCode().equals(params.getTdys())) {
            leqiAbility = LeqiAbilityEnum.BDCZL;
        } else if (TdysEnum.TDYS_09.getCode().equals(params.getTdys())) {
            leqiAbility = LeqiAbilityEnum.LKYS;
        } else {
            leqiAbility = LeqiAbilityEnum.COLLECT;
        }

        leqiHeader.setJrdwptbh(jrdwptbh);
        leqiHeader.setSydwptbh(params.getSydwptbh());
        leqiHeader.setFwbm(leqiApiEnum.getApiCode());
        leqiHeader.setNlbm(leqiAbility.getAbilityCode());
        leqiHeader.setYlbm(leqiAbility.getUseCasesCode());
        leqiHeader.setRequestUrl(url + leqiAbility.getAbilityCode() + "/" + leqiApiEnum.getApiCode() + "/");
        // 仅适用于能力开通后或能力审核中时进行沙箱调用，能力未提交审核前不要加上此参数
        if (StringUtils.isNotBlank(sxcsbz)) {
            leqiHeader.setSxcsbz(sxcsbz);
        }

        return leqiHeader;
    }
}
